package com.uuah.server.common.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

import org.apache.commons.lang.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.uuah.utils.StringUtils;
import com.uuah.utils.UuahUtils;

public class UuahClientCodeUtils {
	private static Logger logger = LoggerFactory
			.getLogger(UuahClientCodeUtils.class);

	public static String getHexStringByUuahBusiMessage(int basicVer, int length,
			byte[] transactionId, int type, String revered, int code,
			int dataLength, byte[] data) {
		StringBuffer sb = new StringBuffer();
		byte[] temp;
		try {
			sb.append(StringUtils.toHexString(new byte[] { (byte) basicVer },
					true));
			logger.debug("basicVer:" + 1);
			temp = UuahUtils.integer2ByteArray(length, 3);
			logger.debug("length:" + temp.length);
			sb.append(StringUtils.toHexString(temp, true));
			temp = transactionId;
			logger.debug("transactionId:" + temp.length);
			sb.append(StringUtils.toHexString(temp, true));
			sb
					.append(StringUtils.toHexString(new byte[] { (byte) type },
							true));
			logger.debug("type:" + 1);
			temp = revered.getBytes("UTF-8");
			logger.debug("revered:" + temp.length);
			sb.append(StringUtils.toHexString(temp, true));
			temp = UuahUtils.integer2ByteArray(code, 4);
			logger.debug("code:" + temp.length);
			sb.append(StringUtils.toHexString(temp, true));

			temp = UuahUtils.integer2ByteArray(dataLength, 4);
			logger.debug("dataLength:" + temp.length);
			sb.append(StringUtils.toHexString(temp, true));
			logger.debug("dataLength-:" + data.length);
			sb.append(StringUtils.toHexString(data, true));
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		logger.debug("ʮ����Ƴ���:" + sb.toString().length());
		return sb.toString();
	}

	public static UuahCodeResult getHexStringByUuahBusiMessage(int basicVer,
			byte[] transactionId, int type, String revered, int code,
			Object[] objs) {
		byte[] temp = new byte[] {};
		for (Object obj : objs) {
			if (obj instanceof String) {
				try {
					temp = ArrayUtils.addAll(temp, ((String) obj)
							.getBytes("UTF-8"));
					temp = ArrayUtils.add(temp, (byte) 0x00);
				} catch (UnsupportedEncodingException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			} else if (obj instanceof Byte) {
				temp = ArrayUtils.add(temp, Byte.parseByte(obj.toString()));
			} else {
				temp = ArrayUtils.addAll(temp, UuahUtils
						.integer2ByteArray(Integer.valueOf(obj.toString())));
			}
		}
		String hex = getHexStringByUuahBusiMessage(basicVer, 32 + temp.length,
				transactionId, type, revered, code, temp.length, temp);
		UuahCodeResult uuahCodeResult = new UuahCodeResult();
		uuahCodeResult.setContent(hex);
		uuahCodeResult.setDataLength(temp.length);
		uuahCodeResult.setLength(32 + temp.length);
		return uuahCodeResult;
	}

	public static byte[] getByteArrayByUuahBusiMessage(int basicVer, int length,
			byte[] transactionId, int type, String revered, int code,
			int dataLength, byte[] data) throws IOException {
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		byte[] temp;
		try {
			out.write(new byte[] { (byte) basicVer });
			logger.debug("basicVer:" + 1);
			temp = UuahUtils.integer2ByteArray(length, 3);
			logger.debug("length:" + temp.length);
			out.write(temp);
			temp = transactionId;
			logger.debug("transactionId:" + temp.length);
			out.write(temp);
			out.write(new byte[] { (byte) type });
			logger.debug("type:" + 1);
			temp = revered.getBytes("UTF-8");
			logger.debug("revered:" + temp.length);
			out.write(temp);
			temp = UuahUtils.integer2ByteArray(code, 4);
			logger.debug("code:" + temp.length);
			out.write(temp);

			temp = UuahUtils.integer2ByteArray(dataLength, 4);
			logger.debug("dataLength:" + temp.length);
			out.write(temp);
			logger.debug("dataLength-:" + data.length);
			out.write(data);
		} catch (UnsupportedEncodingException e) {
			logger.error("{}", e);
		}
		return out.toByteArray();
	}

	public static UuahCodeResult getByteArrayByUuahBusiMessage(int basicVer,
			byte[] transactionId, int type, String revered, int code,
			Object[] objs, int[] paramsByteLenths) throws IOException {
		byte[] temp = new byte[] {};
		int index = 0;
		for (Object obj : objs) {
			if (obj == null) {
				// TODO
			}
			if (obj instanceof String) {
				try {
					if (paramsByteLenths != null
							&& paramsByteLenths[index] == 0) {
						temp = ArrayUtils.addAll(temp, ((String) obj)
								.getBytes("UTF-8"));
						temp = ArrayUtils.add(temp, (byte) 0x00);
					} else if (paramsByteLenths != null
							&& paramsByteLenths[index] > 0) {
						try {
							byte[] fieldArray = new byte[paramsByteLenths[index]];
							byte[] strArray = ArrayUtils.subarray(
									((String) obj).getBytes("UTF-8"), 0,
									paramsByteLenths[index]);
							ArrayUtils.reverse(strArray);
							System.arraycopy(strArray, 0, fieldArray, 0,
									strArray.length);
							ArrayUtils.reverse(fieldArray);
							temp = ArrayUtils.addAll(temp, fieldArray);
						} catch (UnsupportedEncodingException e) {
							logger.error("{}", e.getMessage());
						}
					} else {
						temp = ArrayUtils.addAll(temp, ((String) obj)
								.getBytes("UTF-8"));
						temp = ArrayUtils.add(temp, (byte) 0x00);
					}

				} catch (UnsupportedEncodingException e) {
					logger.error("{}", e);
				}
			} else if (obj instanceof Integer) {
				temp = ArrayUtils.addAll(temp, UuahUtils
						.integer2ByteArray((Integer) obj));
			} else if (obj instanceof Long) {
				temp = ArrayUtils.addAll(temp, UuahUtils
						.integer2ByteArray(Integer.valueOf(obj.toString())));
			} else if (obj instanceof Byte) {
				temp = ArrayUtils.addAll(temp, UuahUtils.integer2ByteArray(Byte
						.valueOf(obj.toString()), 1));
			} else if (obj instanceof byte[]) {
				temp = ArrayUtils.addAll(temp, (byte[]) obj);
			} else {
				temp = ArrayUtils.addAll(temp, UuahUtils
						.integer2ByteArray(Integer.valueOf(obj.toString())));
			}
			index++;
		}
		byte[] result = getByteArrayByUuahBusiMessage(basicVer,
				32 + temp.length, transactionId, type, revered, code,
				temp.length, temp);
		UuahCodeResult uuahCodeResult = new UuahCodeResult();
		uuahCodeResult.setContent(result);
		uuahCodeResult.setDataLength(temp.length);
		uuahCodeResult.setLength(32 + temp.length);
		return uuahCodeResult;
	}

	public static UuahCodeResult getByteArrayByUuahBusiMessage(int basicVer,
			byte[] transactionId, int type, String revered, int code,
			Object[] objs) throws IOException {
		return getByteArrayByUuahBusiMessage(basicVer, transactionId, type,
				revered, code, objs, null);
	}

	public static class UuahCodeResult {
		private Object content;
		private int length;
		private int dataLength;

		public Object getContent() {
			return content;
		}

		public void setContent(Object content) {
			this.content = content;
		}

		public int getLength() {
			return length;
		}

		public void setLength(int length) {
			this.length = length;
		}

		public int getDataLength() {
			return dataLength;
		}

		public void setDataLength(int dataLength) {
			this.dataLength = dataLength;
		}
	}
}
